const net = require("net");
const EventEmitter = require("events");

class SICKRFU extends EventEmitter {
  constructor(ip, port = 2112) {
    super();
    this.ip = ip;
    this.port = port;
    console.log(`SICK RFU630 at ${this.ip}:${this.port}`);
    this.connect();
  }

  connect() {
    // 确保在建立新连接前销毁旧连接
    if (this.connection) {
      try {
        this.connection.destroy();
        this.connection = null;
        console.log(`[${connectTime}] Successfully destroyed old connection`);
      } catch (err) {
        console.error(`[${connectTime}] Error occurred while destroying old connection: ${err.message}`);
      }
    }
    // 尝试建立连接
    const client = net.createConnection({ host: this.ip, port: this.port }, () => {
      this.connection = client;
      this.emit("connected", { 
        ip: this.ip, 
        port: this.port
      });
    });
    // 监听错误事件
    client.on("error", () => {
      this.reconnect();
    });

    // 监听结束事件
    client.on("end", () => {
      this.reconnect(); // 自动重连
    });
    // 监听数据事件
    client.on("data", (data) => {
      const rawData = data.toString();
      console.log(`Received data:`, rawData)
      // 去除首尾的特殊字符(STX和ETX)
      const cleanData = rawData.replace(/^[\x02\x03]+|[\x02\x03]+$/g, '');
      // 按分号分割多组数据
      const dataGroups = cleanData.split(';');

      const parsedData = dataGroups.map(group => {
        // 按冒号分割天线编号和数据部分
        const [fullString, energyValues] = group.split(':');
        // 提取天线编号
        const antennaNo = fullString.split('-')[0];
        // 提取原始label值
        const lable = fullString.split('-')[1];
        // 处理能量值字符串，转换为数组
        const energyArray = energyValues.split(',').map(v => parseInt(v));

        return {
          lable,
          antennaNo,
          energyValues: energyArray
        };
      });
      this.emit("data", parsedData);
    });


  }

  reconnect() {
    // console.log(`Attempting to reconnect to ${this.ip}:${this.port}...`);
    // 持续尝试重连，直到成功
    this.emit("reconnect");
    setTimeout(() => {
      this.connect();
    }, 30000); // 5秒后重连
  }
}

module.exports = SICKRFU;

// 如果直接运行此文件则执行测试
if (require.main === module) {

  // 创建TCP客户端管理器实例
  const manager = new SICKRFU(ip = '192.168.1.63', port = 2112);

  // 存储label信息的Map
  const labelMap = new Map();
  const timeoutTimers = new Map(); // 存储标签超时定时器

  // 监听连接事件
  manager.on('connected', (info) => {
    console.log('Device connected:', info);
  });

  // 监听数据事件
  manager.on('data', (data) => {
    const timestamp = new Date().toLocaleString('zh-CN');
    console.log(`[${timestamp}] Data from location ${this.ip}:`, data);

    // 处理每个标签数据
    data.forEach(item => {
      const { lable, antennaNo } = item;
      const currentTime = Date.now();

      // 更新或创建标签信息
      if (labelMap.has(lable)) {
        const labelInfo = labelMap.get(lable);
        labelInfo.lastSeen = currentTime;

        // 只在天线号发生变化时才记录
        const lastAntennaRecord = labelInfo.antennaHistory[labelInfo.antennaHistory.length - 1];
        if (!lastAntennaRecord || lastAntennaRecord.antennaNo !== antennaNo) {
          labelInfo.antennaHistory.push({
            antennaNo,
            timestamp: currentTime
          });
        }
      } else {
        // 首次检测到标签
        labelMap.set(lable, {
          firstSeen: currentTime,
          lastSeen: currentTime,
          antennaHistory: [{
            antennaNo,
            timestamp: currentTime
          }]
        });

        // 设置30秒超时定时器
        const timeoutTimer = setTimeout(() => {
          const labelInfo = labelMap.get(lable);
          if (labelInfo) {
            const fs = require('fs');
            const path = require('path');
            const logDir = path.join(__dirname, 'logs');

            // 确保日志目录存在
            if (!fs.existsSync(logDir)) {
              fs.mkdirSync(logDir);
            }

            const logFile = path.join(logDir, `rfid_timeout_${new Date().toLocaleDateString('zh-CN').replace(/[/-]/g, '')}.log`);
            const timeoutMsg = `[${new Date().toLocaleString('zh-CN')}] 标签 ${lable} 已超时\n首次读取时间: ${new Date(labelInfo.firstSeen).toLocaleString('zh-CN')}\n最后读取时间: ${new Date(labelInfo.lastSeen).toLocaleString('zh-CN')}\n天线历史记录: ${labelInfo.antennaHistory.map(h => h.antennaNo).join(', ')}\n-------------------\n`;

            console.log(timeoutMsg);
            fs.appendFileSync(logFile, timeoutMsg);
            labelMap.delete(lable);
            timeoutTimers.delete(lable);
          }
        }, 30000);

        timeoutTimers.set(lable, timeoutTimer);
      }

      // 如果标签已存在，重置其超时定时器
      if (timeoutTimers.has(lable)) {
        clearTimeout(timeoutTimers.get(lable));
        const newTimer = setTimeout(() => {
          const labelInfo = labelMap.get(lable);
          if (labelInfo) {
            const fs = require('fs');
            const path = require('path');
            const logDir = path.join(__dirname, 'logs');

            // 确保日志目录存在
            if (!fs.existsSync(logDir)) {
              fs.mkdirSync(logDir);
            }

            const logFile = path.join(logDir, `rfid_timeout_${new Date().toLocaleDateString('zh-CN').replace(/[/-]/g, '')}.log`);
            const timeoutMsg = `标签 ${lable} - 天线 ${labelInfo.antennaHistory.map(h => h.antennaNo).join(', ')}\n`;

            console.log(timeoutMsg);
            fs.appendFileSync(logFile, timeoutMsg);
            labelMap.delete(lable);
            timeoutTimers.delete(lable);
          }
        }, 30000);

        timeoutTimers.set(lable, newTimer);
      }
    });
  });

  // 监听错误事件
  manager.on('error', err => {
    console.log(`Error occurred at location ${this.ip}:`, err);
  });

  // 监听断开连接事件
  manager.on('end', (info) => {
    console.log('Device disconnected:', info);
  });

  // 连接所有配置的服务器
  manager.connect();
}
